package com.easyOrder.core.utils;

import com.easyOrder.core.context.WebContext;
import com.easyOrder.core.exception.api.HttpMessageConverterException;
import com.easyOrder.core.context.ThreadWebContextHolder;
import com.easyOrder.core.json.ObjectFormHttpMessageConverter;
import org.apache.log4j.Logger;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public final class ParametersUtil {
	
	private static final Logger logger = Logger.getLogger(ObjectFormHttpMessageConverter.class);
	
	private static final int BUFFER_LENGTH = 512;

	/**
	 * 从指定 HttpServletRequest 获取参数集合。
	 * 
	 * @param request
	 *            HTTP 请求。
	 * @return 参数集合。
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, String> getParameters(HttpServletRequest request) {
		WebContext webContext = ThreadWebContextHolder.getContext();
		if (null != webContext) {
			Map<String, String> parameters = webContext.getParameters();
			if (null == parameters) {
				// 如内容长度大于 0，则从流中取参数
				if (request.getContentLength() > 0) {
					try {
						parameters = getParameters(request.getInputStream());
					} catch (Exception e) {
						logger.error(e, e);
						throw new HttpMessageConverterException(e);
					}
				}
				// 否则，从 request 的参数表中取参数
				else {
					parameters = getParameters(request.getParameterMap());
				}
				webContext.setParameters(parameters);
			}
			return parameters;
		}
		return null;
	}

	public static Long eTagToVersion(String eTag) {
		return Long.parseLong(eTag, 16) + 99999999;
	}

	public static String versionToETag(Long version) {
		return Long.toString(version - 99999999, 16);
	}

	private static Map<String, String> getParameters(InputStream inputStream) {
		// 将流读到 StringBuilder
		HashMap<String, String> parameters = new HashMap<String, String>();
		StringBuilder builder = new StringBuilder(BUFFER_LENGTH);
		try {
			BufferedReader reader = new BufferedReader(new InputStreamReader(
					inputStream));
			int charCount;
			char[] buffer = new char[BUFFER_LENGTH];
			while ((charCount = reader.read(buffer, 0, buffer.length)) != -1) {
				builder.append(buffer, 0, charCount);
			}
		} catch (Exception e) {
			throw new HttpMessageConverterException(e);
		}
		// 从 StringBuilder 中取得参数
		int elementSeparator = -1;
		int nameValueSeparator = -1;
		int length = builder.charAt(builder.length() - 1) == '&' ? builder
				.length() - 1 : builder.length();
		for (int i = 0; i < length; i++) {
			char ch = builder.charAt(i);
			if ((ch == '&') || (i == length - 1)) {
				if (i == length - 1) {
					i++;
				}
				if ((nameValueSeparator != -1) && (nameValueSeparator + 1 < i)) {
					String parameterName = builder.substring(
							elementSeparator + 1, nameValueSeparator);
					String parameterValue = builder.substring(
							nameValueSeparator + 1, i);
					try {
						parameterValue = URLDecoder.decode(parameterValue,
								"utf-8");
					} catch (UnsupportedEncodingException e) {
						throw new HttpMessageConverterException(e);
					}
					parameters.put(parameterName, parameterValue);
				}
				elementSeparator = i;
				nameValueSeparator = -1;
			} else if ((ch == '=') && (nameValueSeparator == -1)) {
				nameValueSeparator = i;
			}
		}
		return parameters;
	}

	private static Map<String, String> getParameters(Map<String, String[]> map) {
		HashMap<String, String> parameters = new HashMap<String, String>();
		Iterator<Map.Entry<String, String[]>> iterator = map.entrySet()
				.iterator();
		while (iterator.hasNext()) {
			Map.Entry<String, String[]> entry = iterator.next();
			parameters.put(entry.getKey(), entry.getValue()[0]);
		}
		return parameters;
	}
}
